package cc.rengu.redp.bizimpl.upmp.service.impl;

import cc.rengu.redp.bizimpl.enums.BizDataAuditStatusEnum;
import cc.rengu.redp.bizimpl.enums.BizDataStatusEnum;
import cc.rengu.redp.bizimpl.enums.BizOprEnum;
import cc.rengu.redp.bizimpl.enums.PageOptFlagEnum;
import cc.rengu.redp.bizimpl.upmp.common.BusinessContainer;
import cc.rengu.redp.bizimpl.upmp.dao.MarketInfoMapper;
import cc.rengu.redp.bizimpl.upmp.domain.*;
import cc.rengu.redp.bizimpl.upmp.service.*;
import cc.rengu.redp.bizimpl.upmp.vo.OperationResult;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.Common;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.bizimpl.utils.DateUtils;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.common.utils.SortUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * @author 刘玉亮.LL
 */
@Service
public class MarketInfoServiceImpl extends ServiceImpl<MarketInfoMapper, MarketInfo> implements IMarketInfoService {
    @Autowired
    private IUpmpPrivilegeCheckService authPrivilegeCheckService;

    @Autowired
    private IBizTmpService bizTmpService;
    @Autowired
    private IBizHisService bizHisService;

    @Autowired
    private IUpmpOrganizationService organizationService;

    @Autowired
    private IUpmpSysParamService upmpSysParamService;

    @Autowired
    private IUpmpSysSeqService upmpSysSeqService;

    @Autowired
    private IUpmpBMchntBaseInfoService bMchntBaseInfoService;


    @Override
    public IPage<MarketInfo> findByPage(QueryRequest request, MarketInfo info) {
        LambdaQueryWrapper<MarketInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 当前登录用户
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        if (null != user && user.isAdmin()) {
            String instId = info.getInstId();
            if(StringUtils.isBlank(instId)){
                instId = user.getInstId();
            }
            queryWrapper.eq(MarketInfo::getInstId,instId);
        } else {
//            queryWrapper.in(MarketInfo::getCrtOrgId, GZIPUtils.uncompressToString(user.getUserOrgCodes()));
        }
        if (StringUtils.isNotBlank(info.getGroupMchntNo())) {
            queryWrapper.like(MarketInfo::getGroupMchntNo, info.getGroupMchntNo());
        }
        if (StringUtils.isNotBlank(info.getGroupMchntName())) {
            queryWrapper.like(MarketInfo::getGroupMchntName, info.getGroupMchntName());
        }
        if (StringUtils.isNotBlank(info.getManageInstId())) {
            queryWrapper.like(MarketInfo::getManageInstId, info.getManageInstId());
        }

        Page<MarketInfo> page = new Page<>();
        SortUtil.handlePageSort(request, page, true);
        return this.page(page, queryWrapper);
    }
 @Override
    public IPage<MarketInfo> marketIinfoSelect2List(QueryRequest request, String q) {
        LambdaQueryWrapper<MarketInfo> queryWrapper = new LambdaQueryWrapper<>();
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        q = q.replaceAll("&amp;", "&");
        String[] param = q.split("&");
        if (null != param && param.length > 0) {
            queryWrapper.or(qw -> qw.likeRight(MarketInfo::getGroupMchntNo, param[0])
                    .likeRight(MarketInfo::getGroupMchntName, param[0])
                    .likeRight(MarketInfo::getManageInstId, param[0]));
        }
        // 审批状态：02-审批通过，42-修改 审批通过，22-停用 审批通过，32-启用 审批通过，12-注销 审批通过
        queryWrapper.in(MarketInfo::getAuditStatus, BusinessContainer.status_02 + "," + BusinessContainer.status_42 + ","
                + BusinessContainer.status_22 + "," + BusinessContainer.status_32 + "," + BusinessContainer.status_12);
//        queryWrapper.in(MarketInfo::getCrtOrgId, GZIPUtils.uncompressToString(user.getUserOrgCodes()));

        Page<MarketInfo> page = new Page<>();
        SortUtil.handlePageSort(request, page, true);
        return this.page(page, queryWrapper);
    }


    /**
     * 通过编号查询集团商户正式信息
     *
     * @param groupMchntNo 集团商户编号
     * @return
     */
    @Override
    public MarketInfo findByCode(String groupMchntNo) {
        LambdaQueryWrapper<MarketInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MarketInfo::getGroupMchntNo, groupMchntNo);
        return this.getOne(wrapper);
    }

    @Transactional(value = "transactionManager")
    @Override
    public OperationResult saveData(String oprMenuId, String oprMenuName, MarketInfo entity, HttpServletRequest request, String webNextUrl) throws RedpException {
        String flag = request.getParameter("optFlag");
        java.util.Map<String, Object> result = com.google.common.collect.Maps.newHashMap();
        String lastUpddt = DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        String instId = entity.getInstId();
        String crtOrgId = "";

        if (flag.equals("add") && user.isAdmin()) {
            if (StringUtils.isEmpty(instId)) {
                log.error("保存数据时请先选择法人行!");
                return OperationResult.buildFailureResult("保存数据时请先选择法人行!");
            } else {
                UpmpOrganization headOrg = organizationService.getHeadOrgByCode(instId);
                crtOrgId = (headOrg == null ? user.getOrgCode() : headOrg.getOrgCode());
            }
        } else {
            instId = (instId == null ? user.getInstId() : instId);
            crtOrgId = (entity.getCrtOrgId() == null ? user.getOrgCode() : entity.getCrtOrgId());
        }
        UpmpOrganization org = organizationService.getOrgByCode(crtOrgId, instId);
        // 国家代码：156-CHN
        entity.setNationCd("156");
        entity.setArtifCertType("01");
        entity.setGroupMchntNameAbb(entity.getGroupMchntName());
        entity.setManageInstId(user.getOrgCode());
        //
        if (PageOptFlagEnum.OPT_FLAG_ADD.getType().equals(flag)) {

            UpmpPrivilegeCheck privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(user.getInstId(), "marketInfo:add");
            //
            entity.setId(null);
            entity.setGroupMchntNo(getNextMerInnerCd(entity.getRegisterArea(), entity.getCupsMcc()));
            entity.setOprId(user.getId());
            entity.setCrtOrgId(org.getOrgCode());
            entity.setCreateTime(lastUpddt);
            entity.setLastOprId(user.getId());
            entity.setLastUpdateTime(lastUpddt);
            //
            if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {
                entity.setGroupMchntStatus(BizDataStatusEnum.STATUS_DRAFT.getType());
                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_CHECKING.getType());
                this.saveOrUpdate(entity);

                bizTmpService.saveBizTmp(entity, user, org.getInstId(), BizOprEnum.OPR_ADD.getType(), lastUpddt
                        , oprMenuId, oprMenuName, entity.getGroupMchntStatus(), entity.getAuditStatus(), String.valueOf(entity.getId()), webNextUrl, null, null, null);
                result.put("id", entity.getId());
            } else {
                entity.setGroupMchntStatus(BizDataStatusEnum.STATUS_NORMAL.getType());
                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_PASS.getType());
                this.saveOrUpdate(entity);

                bizHisService.saveBizHisNew(entity, entity, user, org.getInstId(), BizOprEnum.OPR_ADD.getType(), lastUpddt
                        , oprMenuId, oprMenuName, String.valueOf(entity.getId()), null, null, null);
                result.put("id", entity.getId());
            }
        } else if (PageOptFlagEnum.OPT_FLAG_UPDATE.getType().equals(flag)) {
            String id = request.getParameter("id");
            if (Common.isBlank(id)) {
                 log.error("请求参数(id)异常!");
                return OperationResult.buildFailureResult("请求参数(id)异常!", result);
            }

            UpmpPrivilegeCheck privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(user.getInstId(), "marketInfo:edit");
            MarketInfo dbMarketInfo = this.getById(id);
            MarketInfo marketInfo = new MarketInfo();
            BeanUtils.copyProperties(entity, marketInfo);

            entity.setLastOprId(user.getId());
            entity.setLastUpdateTime(lastUpddt);
            if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {
                dbMarketInfo.setLastOprId(user.getId());
                dbMarketInfo.setLastUpdateTime(lastUpddt);
                dbMarketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_CHECKING.getType());

                this.saveOrUpdate(dbMarketInfo);

                //检查临时表是否有数据，如果没用则新增
                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_CHECKING.getType());
                marketInfo = new MarketInfo();
                BeanUtils.copyProperties(dbMarketInfo, marketInfo);
                BeanUtils.copyProperties(entity, marketInfo);

                bizTmpService.saveBizTmp(marketInfo, user, org.getInstId(), BizOprEnum.OPR_UPDATE.getType(), lastUpddt
                        , oprMenuId, oprMenuName, dbMarketInfo.getGroupMchntStatus(), dbMarketInfo.getAuditStatus(), String.valueOf(dbMarketInfo.getId()), webNextUrl, null, null, null);
                result.put("id", dbMarketInfo.getId());
            } else {
                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());

                BeanUtils.copyProperties(entity, marketInfo);

                this.saveOrUpdate(marketInfo);

                //历史表新增
                bizHisService.saveBizHisNew(marketInfo, dbMarketInfo, user, org.getInstId(), BizOprEnum.OPR_UPDATE.getType(), lastUpddt
                        , oprMenuId, oprMenuName, String.valueOf(marketInfo.getId()), null, null, null);
            }
        } else if (PageOptFlagEnum.OPT_FLAG_STOP.getType().equals(flag)
                || PageOptFlagEnum.OPT_FLAG_USE.getType().equals(flag)
                || PageOptFlagEnum.OPT_FLAG_CANCEL.getType().equals(flag)) {
            String id = request.getParameter("id");
            if (Common.isBlank(id)) {
                 log.error("请求参数(id)异常!");
                return OperationResult.buildFailureResult("请求参数(id)异常!", result);
            }
            MarketInfo dbMarketInfo = this.getById(id);

            if (Common.isBlank(dbMarketInfo)) {
                 log.error("根据id没有找到指定数据！");
                return OperationResult.buildFailureResult("根据id没有找到指定数据！", result);
            }

            MarketInfo marketInfo = new MarketInfo();
            BeanUtils.copyProperties(dbMarketInfo, marketInfo);

            UpmpPrivilegeCheck privilegeCheck = new UpmpPrivilegeCheck();
            String bizOpr = "";
            if (PageOptFlagEnum.OPT_FLAG_STOP.getType().equals(flag)) {
                bizOpr = BizOprEnum.OPR_STOP.getType();
                privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(user.getInstId(), "marketInfo:stop");
                if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_STOP_CHECKING.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_STOP_PASS.getType());
                }
            } else if (PageOptFlagEnum.OPT_FLAG_USE.getType().equals(flag)) {

                bizOpr = BizOprEnum.OPR_USE.getType();
                privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(user.getInstId(), "marketInfo:use");
                if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_USE_CHECKING.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_USE_PASS.getType());
                }
            } else if (PageOptFlagEnum.OPT_FLAG_CANCEL.getType().equals(flag)) {
                List<UpmpBMchntBaseInfo> ls = bMchntBaseInfoService.getBMchntBaseInfoByGroupMchntNo(marketInfo.getGroupMchntNo());
                if (null != ls && ls.size() > 0) {
                    return OperationResult.buildFailureResult("存在使用此集团商户的正式商户，无法完成此操作", result);
                }
                //保存注销原因
                String cancelReason = request.getParameter("cancelReason");
                marketInfo.setCancelReason(cancelReason);
                bizOpr = BizOprEnum.OPR_CANCEL.getType();
                privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(user.getInstId(), "marketInfo:delete");
                if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_CANCEL_CHECKING.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_CANCEL_PASS.getType());
                    marketInfo.setGroupMchntStatus(BizDataStatusEnum.STATUS_CANCELED.getType());
                }
            }
            marketInfo.setLastOprId(user.getId());
            marketInfo.setLastUpdateTime(lastUpddt);

            this.saveOrUpdate(marketInfo);

            if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {
                //检查临时表是否有数据，如果没用则新增
                bizTmpService.saveBizTmp(marketInfo, user, org.getInstId(), bizOpr, lastUpddt
                        , oprMenuId, oprMenuName, marketInfo.getGroupMchntStatus(), marketInfo.getAuditStatus(), marketInfo.getId(), webNextUrl, null, null, null);
            } else {
                //历史表新增
                bizHisService.saveBizHisNew(marketInfo, dbMarketInfo, user, org.getInstId(), bizOpr, lastUpddt
                        , oprMenuId, oprMenuName, String.valueOf(marketInfo.getId()), null, null, null);
            }
        } else if (PageOptFlagEnum.OPT_FLAG_CHECK.getType().equals(flag)) {
            String id = request.getParameter("id");
            if (Common.isBlank(id)) {
                 log.error("请求参数(id)异常!");
                return OperationResult.buildFailureResult("请求参数(id)异常!", result);
            }

            //获取临时表数据并转换成实体对象
            BizTmp tmp = bizTmpService.getById(id);
            if (Common.isBlank(tmp)) {
                 log.error("根据id没有找到指定临时表数据！");
                return OperationResult.buildFailureResult("根据id没有找到指定临时表数据！", result);
            }
            String bizdata = "";
            if (null != tmp.getBizData1()) {
                bizdata += tmp.getBizData1();
            }
            if (null != tmp.getBizData2()) {
                bizdata += tmp.getBizData2();
            }
            if (null != tmp.getBizData3()) {
                bizdata += tmp.getBizData3();
            }
            // 临时表数据
            MarketInfo marketInfoNew = JSON.parseObject(bizdata, MarketInfo.class);
            // 正式表数据
            MarketInfo marketInfo = this.getById(id);
            // 备份正式表数据
            MarketInfo marketInfoOld = new MarketInfo();
            BeanUtils.copyProperties(marketInfo, marketInfoOld);
            //
            if (Common.isBlank(marketInfo) && !BizOprEnum.OPR_ADD.equals(tmp.getBizOpr())) {
                 log.error("根据id没有找到指定数据！");
                return OperationResult.buildFailureResult("根据id没有找到指定数据！", result);
            }

            String opt = request.getParameter("opt");
            if (Common.isBlank(opt)) {
                 log.error("请求参数(opt)异常!");
                return OperationResult.buildFailureResult("请求参数(opt)异常!", result);
            }
            //
            if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                // 审批通过将临时表数据更新到正式表
                BeanUtils.copyProperties(marketInfoNew, marketInfo);
            } else {
                String approvalRefuseReason = request.getParameter("approvalRefuseReason");
                marketInfo.setAuditRefuseReason(approvalRefuseReason);
            }
            String bizOpr = "";
            if (BizDataAuditStatusEnum.AUDIT_STATUS_ADD_CHECKING.getType().equals(marketInfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_PASS.getType());
                    marketInfo.setGroupMchntStatus(BizDataStatusEnum.STATUS_NORMAL.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_REJECT.getType());
                    marketInfo.setAuditRefuseReason(entity.getAuditRefuseReason());
                }
                bizOpr = BizOprEnum.OPR_ADD.getType();
            } else if (BizDataAuditStatusEnum.AUDIT_STATUS_CANCEL_CHECKING.getType().equals(marketInfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_CANCEL_PASS.getType());
                    marketInfo.setGroupMchntStatus(BizDataStatusEnum.STATUS_CANCELED.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_CANCEL_REJECT.getType());
                    marketInfo.setAuditRefuseReason(entity.getAuditRefuseReason());
                }
                bizOpr = BizOprEnum.OPR_CANCEL.getType();
            } else if (BizDataAuditStatusEnum.AUDIT_STATUS_STOP_CHECKING.getType().equals(marketInfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_STOP_PASS.getType());
                    marketInfo.setGroupMchntStatus(BizDataStatusEnum.STATUS_STOPED.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_STOP_REJECT.getType());
                    marketInfo.setAuditRefuseReason(entity.getAuditRefuseReason());
                }
                bizOpr = BizOprEnum.OPR_STOP.getType();
            } else if (BizDataAuditStatusEnum.AUDIT_STATUS_USE_CHECKING.getType().equals(marketInfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_USE_PASS.getType());
                    marketInfo.setGroupMchntStatus(BizDataStatusEnum.STATUS_NORMAL.getType());
                } else {
                    marketInfo.setGroupMchntStatus(BizDataAuditStatusEnum.AUDIT_STATUS_USE_REJECT.getType());
                    marketInfo.setAuditRefuseReason(entity.getAuditRefuseReason());
                }
                bizOpr = BizOprEnum.OPR_USE.getType();
            } else if (BizDataAuditStatusEnum.AUDIT_STATUS_UPD_CHECKING.getType().equals(marketInfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());
                    marketInfo.setGroupMchntStatus(BizDataStatusEnum.STATUS_NORMAL.getType());
                } else {
                    marketInfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_REJECT.getType());
                    marketInfo.setAuditRefuseReason(entity.getAuditRefuseReason());
                }
                bizOpr = BizOprEnum.OPR_UPDATE.getType();
            }
            // 状态赋值完成后，入库正式表
            this.saveOrUpdate(marketInfo);
            //
            if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                //审批通过将正式表更新到历史表
                bizHisService.saveBizHisNew(marketInfo, marketInfoOld, user, org.getInstId(), bizOpr, lastUpddt, oprMenuId, oprMenuName, String.valueOf(marketInfo.getId()), null, null, null);
            }
            // 修改临时表的审核状态等字段
            bizTmpService.saveBizTmp(marketInfo, user, org.getInstId(), bizOpr, lastUpddt, oprMenuId, oprMenuName, marketInfo.getGroupMchntStatus(), marketInfo.getAuditStatus(), String.valueOf(marketInfo.getId()), webNextUrl, null, null, null);
        }

        return OperationResult.buildSuccessResult("数据保存处理完成", result);
    }

    /**
     * 格式为:收单行代码(3 位) + 银联地区码+ MCC代码(4 位)+ 序列号(4 位)
     *
     * @param unionArea 地区代码
     * @param mccCode   行业代码 mcc
     * @return
     */
    private String getNextMerInnerCd(String unionArea, String mccCode) {
        String s = upmpSysSeqService.updateParamValue(unionArea, mccCode, "20");
        String index = String.format("%04d", Integer.parseInt(s));
        return BusinessContainer.mngOrgCode + unionArea + mccCode + index;
    }

    @Override
    public MarketInfo findOneByCode(String groupMchntNo, String status, String instId) {
        LambdaQueryWrapper<MarketInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MarketInfo::getGroupMchntNo,groupMchntNo);
        queryWrapper.eq(MarketInfo::getGroupMchntStatus,status);
        queryWrapper.eq(MarketInfo::getInstId,instId);
        return this.getOne(queryWrapper);
    }
}
